package com.inibb.app.sftp;

import java.io.File;
import java.net.InetAddress;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.JPasswordField;

import com.inibb.app.sftp.exception.SFTPException;



/**
 * This is the factory of SFTPConnection.  
 * Factory instance can be created by static method
 * <code>getFactoryInstance</code> with the name real implementation class.
 * Or by static method <code>getDefaultFactoryInstance</code> 
 * to get a default factory instance using default implementation class.<p>
 * With the factory instance, SFTPConnection implementation can be instantiated
 * using method <code>getInstance</code>.
 * @author PCCW
 *
 */
public class SFTPConnectionFactory
{
	private static final String DEFAULT_IMPL_CLASSNAME = "com.pccw.oframework.sftp.impl.jsch.JschSFTPConnection";
	private static SFTPConnectionFactory DEFAULT_FACTORY_INSTANCE = null;
	
	private Class implClass = null;
	
	private SFTPConnectionFactory() {
		
	}
		
	public static SFTPConnectionFactory getFactoryInstance(String implClassName) 
		throws ClassNotFoundException
	{
		SFTPConnectionFactory _instance = new SFTPConnectionFactory();
		_instance.implClass = Class.forName(implClassName);
		return _instance;
	}
	
	public static SFTPConnectionFactory getDefaultFactoryInstance() {
		if (DEFAULT_FACTORY_INSTANCE==null) {
			synchronized(DEFAULT_IMPL_CLASSNAME) {
				if (DEFAULT_FACTORY_INSTANCE==null) {
					SFTPConnectionFactory _instance = new SFTPConnectionFactory();
					try {
						_instance.implClass = Class.forName(DEFAULT_IMPL_CLASSNAME);
					} catch (ClassNotFoundException cnfe) {
						SFTPException sftpe = new SFTPException(SFTPException.CODE_RUNTIME,"Error when loading default SFTP impl class:"+DEFAULT_IMPL_CLASSNAME,cnfe);
						throw new RuntimeException(sftpe);
					}
					DEFAULT_FACTORY_INSTANCE = _instance; 
				}
			}
		}
		return DEFAULT_FACTORY_INSTANCE;
	}
	
	public Class getImplClass() {
		return implClass;
	}
	
	public SFTPConnection getInstance() {
		try {
			return (SFTPConnection)implClass.newInstance();
		} catch (IllegalAccessException iae) {
			SFTPException sftpe = new SFTPException(SFTPException.CODE_RUNTIME,"Error when instantiating SFTPConnection using class:"+implClass,iae);
			throw new RuntimeException(sftpe);
		} catch (InstantiationException ie) {
			SFTPException sftpe = new SFTPException(SFTPException.CODE_RUNTIME,"Error when instantiating SFTPConnection using class:"+implClass,ie);
			throw new RuntimeException(sftpe);
		}
	}
	
	
	public static void main(String[] args) 
		throws Exception
	{
		JPasswordField passwordField = (JPasswordField) new JPasswordField(20);
		
		if (args.length==0) {
			System.out.println("Usage: java com.pccw.oframework.sftp.SFTPConnectionFactory <connectionString> [ --keyFile <keyFile> ] [ --dir <dir>]" );
			System.out.println("  connectionString : userid@host:port");
			return;
		}
		String connectString = args[0];
		String dir = null;
		File keyFile = null; 
		char[] passwd = null;
		
		for (int i=1; i<args.length; i++) {
			if (args[i].trim().equals("--keyFile")) {
				keyFile = new File(args[++i]);
			}
			if (args[i].trim().equals("--dir")) {
				dir = args[++i];
			}
		}
		
		Object[] ob = { passwordField };
		int result = JOptionPane.showConfirmDialog(null, ob, "Please input the password",
				JOptionPane.OK_CANCEL_OPTION);
		if (result == JOptionPane.OK_OPTION) {
			passwd = passwordField.getPassword();
		} else {
		}
		
		
		
		int atIdx = connectString.indexOf("@");
		String userid = connectString.substring(0,atIdx);
		
		int colonIdx = connectString.indexOf(":");
		String host = null;
		int port = 22;
		
		if (colonIdx>0) {
			host = connectString.substring(atIdx+1,colonIdx);
			port = Integer.parseInt(connectString.substring(colonIdx+1));
		} else {
			host = connectString.substring(atIdx+1);
		}
		
		SFTPAuthInfo auth = new SFTPAuthInfo(userid,keyFile,passwd);
		
		SFTPConnection conn = getDefaultFactoryInstance().getInstance();
		conn.connect(InetAddress.getByName(host),port,auth);
		
		List l = conn.list(new RemoteFileEntry(dir));
		for (int i=0;i<l.size();i++) {
			System.out.println(l.get(i).toString());
		}
		
		//conn.rename(new RemoteFileEntry("adfadf"),new RemoteFileEntry("adfadf2"));
		
		conn.disconnect();
		
	}

}
